<template>
    <div class="maftools-page">
        <el-card v-loading="loading" shadow="hover">
            <div class="header" style="display: flex; align-items: center; justify-content: space-between">
                <div>
                    <h2 style="margin: 0">MAF Tools 图表（默认 & 上传）</h2>
                    <p class="hint" style="margin: 0 10px 0 0; color: #666">
                        页面初始显示全量 WES 的默认图。若上传 SampleID 文件，则显示基于上传样本筛选后的自定义图并提供
                        ZIP 下载。
                    </p>
                </div>

                <el-select
                    v-model="selectedWes"
                    placeholder="选择 WES 源"
                    size="small"
                    filterable
                    :loading="sourcesLoading"
                    style="min-width: 150px; max-width: 200px;"
                    @change="onSelectWes"
                    >
                    <el-option
                        v-for="s in wesSources"
                        :key="s.id"
                        :label="`${s.name} (${new Date(s.mtime * 1000).toLocaleString()})`"
                        :value="s.name"
                    />
                </el-select>

                <div style="display: flex; align-items: center; gap: 8px">
                    <el-button size="small" @click="refreshDefault" title="重新加载默认图">刷新默认图</el-button>
                    <el-button size="small" type="info" @click="resetToDefault" v-if="uploadResult">
                        重置为默认图
                    </el-button>
                </div>
            </div>

            <el-row :gutter="20" style="margin-top: 14px">
                <!-- Upload column: 缩小为 span=6 -->
                <el-col :span="6">
                    <el-card class="upload-card">
                        <div style="font-weight: 600; margin-bottom: 8px">上传 SampleID 文件（CSV/TXT）</div>

                        <el-upload
                            ref="uploader"
                            class="upload-demo compact"
                            drag
                            action="/"
                            :http-request="noopRequest"
                            :before-upload="beforeUpload"
                            :on-change="onFileChange"
                            :show-file-list="false"
                            :auto-upload="false"
                        >
                            <i class="el-icon-upload" style="font-size: 22px; color: #409eff"></i>
                            <div class="el-upload__text" style="margin-top: 8px; font-size: 13px">
                                拖拽或点击选择文件
                            </div>
                            <div class="el-upload__tip" style="color: #999; margin-top: 6px; font-size: 12px">
                                只需包含 SampleID 列或单列文件。支持 CSV / TSV / TXT。
                            </div>
                        </el-upload>

                        <div style="margin-top: 10px; display: flex; gap: 8px">
                            <el-button type="primary" size="small" :loading="uploading" @click="submitUpload">
                                上传并生成
                            </el-button>
                            <el-button size="small" @click="clearPicked">重置</el-button>
                        </div>

                        <div v-if="pickedInfo" style="margin-top: 8px; color: #666; font-size: 13px">
                            {{ pickedInfo }}
                        </div>
                        <div v-if="uploadMsg" style="margin-top: 6px; color: #c00; font-size: 13px">
                            {{ uploadMsg }}
                        </div>
                    </el-card>
                </el-col>

                <!-- Preview column: 扩大为 span=18 -->
                <el-col :span="18">
                    <el-card>
                        <div style="display: flex; justify-content: space-between; align-items: center">
                            <div style="font-weight: 600">当前显示图表</div>
                            <div style="color: #999; font-size: 13px">
                                <span v-if="uploadResult">显示上传结果（run: {{ uploadResult.run_id }})</span>
                                <span v-else>默认全量分析图</span>
                            </div>
                        </div>

                        <div style="margin-top: 12px; display: flex; gap: 8px; align-items: center">
                            <!-- 上传结果的 ZIP 下载 -->
                            <el-button
                                v-if="uploadResult && uploadResult.zip"
                                type="success"
                                :icon="null"
                                :href="fullUrl(uploadResult.zip)"
                                target="_blank"
                                size="small"
                            >
                                下载自定义图（ZIP）
                            </el-button>

                            <!-- 默认结果的 ZIP 下载（新增） -->
                            <el-button
                                v-else-if="defaultResult && defaultResult.zip"
                                type="primary"
                                :href="fullUrl(defaultResult.zip)"
                                target="_blank"
                                size="small"
                            >
                                下载默认图（ZIP）
                            </el-button>
                        </div>

                        <div style="margin-top: 16px">
                            <template v-if="displayImages && displayImagesKeys.length">
                                <el-row :gutter="16" style="row-gap: 16px">
                                    <!-- 每张大图占整行（span=24） -->
                                    <el-col :span="24" v-for="key in displayImagesKeys" :key="key">
                                        <el-card>
                                            <div
                                                style="
                                                    display: flex;
                                                    justify-content: space-between;
                                                    align-items: center;
                                                "
                                            >
                                                <div style="font-weight: 600">
                                                    {{ niceTitle(key) }}
                                                </div>
                                                <div>
                                                    <!-- 使用 JS 打开图片 -->
                                                    <el-button
                                                        type="text"
                                                        size="small"
                                                        @click="openImage(displayImages[key])"
                                                    >
                                                        打开原图
                                                    </el-button>
                                                    <el-button
                                                        v-if="displayImages[key]"
                                                        type="primary"
                                                        size="small"
                                                        @click="
                                                            download(
                                                                displayImages[key],
                                                                filenameFor(key, displayImages[key])
                                                            )
                                                        "
                                                    >
                                                        下载该图
                                                    </el-button>
                                                </div>
                                            </div>
                                            <div style="margin-top: 10px; display: flex; justify-content: center">
                                                <!-- 图片样式：宽度为容器的100%，但限制最大宽度与高度，防止撑破布局 -->
                                                <img
                                                    :src="fullUrl(displayImages[key])"
                                                    :alt="key"
                                                    class="maf-image"
                                                    loading="lazy"
                                                />
                                            </div>
                                        </el-card>
                                    </el-col>
                                </el-row>
                            </template>

                            <template v-else>
                                <div style="color: #999">
                                    没有可显示的图表（请确认后端已生成或先点击“刷新默认图”）。
                                </div>
                            </template>
                        </div>
                    </el-card>
                </el-col>
            </el-row>
        </el-card>

        <el-dialog
            v-model="progressVisible"
            title="任务执行中"
            :close-on-click-modal="false"
            :show-close="false"
            width="400px"
            >
            <div style="text-align:center; padding: 20px">
                <el-progress :percentage="progress" :status="progressStatus" />
                <p v-if="progress < 100">正在处理，请稍候...</p>
                <p v-else>任务完成！</p>
            </div>
        </el-dialog>
    </div>
</template>

<script setup lang="ts" name="Maftools">
    import { ref, onMounted, onBeforeUnmount } from 'vue';
    import { get, post } from '@/axios/api';
    import { ElMessage } from 'element-plus';
    import { download, fullUrl } from '@/common/util';
    import { usePollingTask } from '@/common/usePollingTask';
    import { loadUser, useAuth } from '@/common/useAuth';
    import { useRoute, useRouter } from 'vue-router';

    const { user } = useAuth();

    // 状态
    const loading = ref(false); // 页面级 loading（默认图加载）
    const uploading = ref(false); // 上传生成时 loading（按钮）
    const pickedFile = ref(null);
    const pickedInfo = ref('');
    const uploadMsg = ref('');
    const defaultResult: any = ref(null); // GET 默认图的结果
    const uploadResult: any = ref(null); // POST 上传结果
    const uploader: any = ref(null);
    const router = useRouter();
    const route = useRoute();

    const displayImages: any = ref({}); // 当前展示的图片对象（来自 defaultResult 或 uploadResult）
    const displayImagesKeys: any = ['oncoplot', 'plotmafSummary', 'rainfallPlot'];

    const progressVisible = ref(false);
    const progress = ref(0);
    const progressStatus = ref<"success" | "exception" | undefined>();

    const wesSources = ref<any[]>([]);
    const sourcesLoading = ref(false);
    const selectedWes = ref<string | null>("wes.250815.csv");


    async function fetchSources() {
        sourcesLoading.value = true;
        try {
            const res = await get('/maftool/sources/');
            wesSources.value = Array.isArray(res) ? res : [];
            // 默认选择第一个（如果没有 uploadResult）
            if (!selectedWes.value && wesSources.value.length) {
                selectedWes.value = wesSources.value[0].name;
            }
        } catch (e: any) {
            console.error('fetch sources fail', e);
            ElMessage.error('获取 WES 源列表失败');
        } finally {
            sourcesLoading.value = false;
        }
    }

    function onSelectWes(val: string) {
        // 选择后立即刷新显示（重新请求 default for that WES）
        fetchDefault();
    }




    const { pollTaskStatus, stopPolling } = usePollingTask();
    function noopRequest() {
        return Promise.resolve();
    }
    function niceTitle(key: any) {
        if (key === 'oncoplot') return 'Oncoplot（Top genes）';
        if (key === 'plotmafSummary') return '综合统计（plotmafSummary）';
        if (key === 'rainfallPlot') return 'Rainfall 突变图';
        return key;
    }

    function displayFrom(obj: any) {
        if (!obj) return {};
        return {
            oncoplot: obj.oncoplot,
            plotmafSummary: obj.plotmafSummary,
            rainfallPlot: obj.rainfallPlot
        };
    }

    // 新增：用 JS 打开图片，确保浏览器行为一致
    function openImage(url: any) {
        const u = fullUrl(url);
        if (!u) {
            ElMessage.warning('未找到图片地址');
            return;
        }
        window.open(u, '_blank', 'noopener,noreferrer');
    }

    // 初始化：拉取默认图
    async function fetchDefault() {
        loading.value = true;
        try {
            // 如果有 selectedWes 则通过 query 传给后端
            const qs = selectedWes.value ? `?wes_name=${encodeURIComponent(selectedWes.value)}` : '';
            const res:any = await get(`maftool/charts/${qs}`);
            if (res && res.task_id) {
                ElMessage.success('任务提交成功，现在将跳转到任务管理页面');
                setTimeout(() => {
                    router.push('/taskpage');
                }, 2000);
                // try {
                //     const taskId = res.task_id;
                //     if (!taskId) {
                //         ElMessage.error('Failed to upload');
                //     }
                //     const apiUrl = `/maftool/charts/polling/${taskId}/`
                //     await pollTaskStatus(
                //         apiUrl,
                //         result => {
                //             // 成功：后端 result 很可能就是你之前 applyResult 需要的对象
                //             try {
                //                 displayImages.value = displayFrom(result);
                //                 progress.value = 100;
                //                 progressStatus.value = 'success';
                //                 setTimeout(() => {
                //                     progressVisible.value = false;
                //                 }, 1000);
                //             } catch (e) {
                //                 console.error('applyResult 处理失败', e);
                //             } finally {
                //                 if (result?.status == 'success' || result?.status == 'failed') {
                //                     loading.value = false;
                //                 }
                //             }
                //         },
                //         err => {
                //             console.error('Task failed or polling error:', err);
                //             // 如果后端给出了 error 文本，展示
                //             ElMessage.error(typeof err === 'string' ? err : '任务执行失败');
                //             loading.value = false;
                //             progressVisible.value = false;
                //         },
                //         res => {
                //             console.log('Polling task status:', res);
                //             progressVisible.value = true
                //             progress.value = res.progress;

                //         },
                //         {
                //             initialDelay: 1000,
                //             maxDelay: 10000,
                //             timeout: 5 * 60 * 1000
                //         }
                //     );
                // } catch (err: any) {
                //     console.error('upload failed', err);
                //     const msg = err?.response?.data?.detail || err.message || '上传或生成失败';
                //     uploadMsg.value = msg;
                //     ElMessage.error(msg);
                // } 
            }
            const payload = res;
            defaultResult.value = payload;
            if (!uploadResult.value) {
                displayImages.value = displayFrom(payload);
            }
        } catch (err: any) {
            console.error('fetch default failed', err);
            ElMessage.error('获取默认图失败：' + (err?.response?.data?.detail || err.message || '未知错误'));
        } finally {
            loading.value = false;
        }

    }

    // 刷新默认图（重新向后端拉取）
    async function refreshDefault() {
        await fetchDefault();
        ElMessage.success('默认图已刷新');
    }

    // 清除上传结果，回默认图
    function resetToDefault() {
        uploadResult.value = null;
        displayImages.value = displayFrom(defaultResult.value);
        ElMessage.info('已恢复显示默认图');
    }

    function beforeUpload(rawFile: any) {
        // 有的版本里 only before-upload 会在拖拽路径不触发，所以我们也写 on-change；这里仍返回 false 阻止自动上传
        setPicked(rawFile);
        return false;
    }

    function onFileChange(file: any /* , fileList */) {
        // 选择/拖入立刻触发，确保 UI 有反应
        const f = file?.raw || file;
        setPicked(f);
    }

    function setPicked(file: any) {
        if (!file) return;
        pickedFile.value = file;
        pickedInfo.value = `已选择：${file.name}（${(file.size / 1024).toFixed(1)} KB）`;
        uploadMsg.value = '';
    }
    function clearPicked() {
        pickedFile.value = null;
        pickedInfo.value = '';
        uploadMsg.value = '';
        uploader.value?.clearFiles?.(); // 关键：重置 input，允许再次选择同名文件
    }

    async function submitUpload() {
        if (!pickedFile.value) {
            ElMessage.warning('请先选择一个包含 SampleID 的文件');
            return;
        }

        uploading.value = true;
        uploadMsg.value = '上传并生成中，请稍候...';
        const baseApiUrl = import.meta.env.VITE_API_BASE_URL;
        try {
            const form = new FormData();
            form.append('file', pickedFile.value);
            if (selectedWes.value) {
                form.append('wes_name', selectedWes.value);
            }
            const res: any = await post('/maftool/charts/upload/', form, {
                headers: { 'Content-Type': 'multipart/form-data' },
                timeout: 180000
            });
            const taskId = res.task_id;
            if (!taskId) {
                ElMessage.error('Failed to upload');
            } else {
                ElMessage.success('任务提交成功，现在将跳转到任务管理页面');
                setTimeout(() => {
                    router.push('/taskpage');
                }, 2000);
            }
            const apiUrl = `/maftool/charts/polling/${taskId}/`
            // await pollTaskStatus(
            //     apiUrl,
            //     result => {
            //         // 成功：后端 result 很可能就是你之前 applyResult 需要的对象
            //         console.log(result)
            //         try {
            //             displayImages.value = displayFrom(result);
            //             progress.value = 100;
            //             progressStatus.value = 'success';
            //             setTimeout(() => {
            //                 progressVisible.value = false;
            //             }, 1000);
            //         } catch (e) {
            //             console.error('applyResult 处理失败', e);
            //         } finally {
            //             if (result?.status == 'success' || result?.status == 'failed') {
            //                 loading.value = false;
            //             }
            //         }
            //     },
            //     err => {
            //         console.error('Task failed or polling error:', err);
            //         // 如果后端给出了 error 文本，展示
            //         ElMessage.error(typeof err === 'string' ? err : '任务执行失败');
            //         loading.value = false;
            //         progressVisible.value = false;
            //     },
            //     res => {
            //         console.log('Polling task status:', res);
            //         progressVisible.value = true
            //         progress.value = res.progress;

            //     },
            //     {
            //         initialDelay: 1000,
            //         maxDelay: 10000,
            //         timeout: 5 * 60 * 1000
            //     }
            // );
        } catch (err: any) {
            console.error('upload failed', err);
            const msg = err?.response?.data?.detail || err.message || '上传或生成失败';
            uploadMsg.value = msg;
            ElMessage.error(msg);
        } finally {
            uploading.value = false;
            // 清除选中文件，便于重复上传同一文件
            clearPicked();
        }
    }

    function filenameFor(key: any, url: any) {
        // 生成一个友好的下载文件名：maftools_<runId|default>_<图名>.扩展名
        const prefix = uploadResult.value ? `maftools_${uploadResult.value.run_id}` : 'maftools_default';
        const clean = (url || '').split('?')[0];
        const m = clean.match(/\.(png|jpg|jpeg|webp|svg)$/i);
        const ext = (m ? m[1] : 'png').toLowerCase();
        return `${prefix}_${key}.${ext}`;
    }

    async function getTaskResult(taskId: string) {
        loading.value = true;
        try {
            const res:any = await get(`/usertasks/${taskId}/`)
            if (res && res.status === 'SUCCESS') {
                displayImages.value = displayFrom(res.result);
                loading.value = false;
            } 
        } catch (e:any) {
            ElMessage.error(e.message);
        }
    }

    // 生命周期
    onMounted(async() => {
        await loadUser(); 
        if (!user.value) {
            ElMessage.error('请先登录');
            setTimeout(() => {
                router.push({name: "login"});
            }, 1000)
        } else {
            const p = route.params as any;
            if (p.taskid === 'init') {
                fetchSources().finally(() => {
                    fetchDefault();
                });
            } else {
                getTaskResult(p.taskid)
            }
        }

    });

    onBeforeUnmount(() => {
        stopPolling();
    });
</script>

<style scoped>
    .maftools-page {
        padding: 12px;
    }
    .hint {
        color: #666;
    }

    /* 上传框更紧凑 */
    .upload-card {
        padding: 12px;
    }
    .upload-demo.compact {
        border: 1px dashed #e6e6e6;
        border-radius: 6px;
        padding: 14px;
        text-align: center;
        cursor: pointer;
    }
    .upload-demo.compact i {
        font-size: 20px;
    }

    /* 图片样式：限制宽高，避免撑破布局 */
    .maf-image {
        width: 100%;
        max-width: 1400px; /* 限制最大宽度，防止过大 */
        height: auto;
        max-height: 850px; /* 限制最大高度 */
        object-fit: contain;
        border-radius: 6px;
        box-shadow: 0 6px 18px rgba(35, 45, 65, 0.06);
    }

    /* 让 el-card 内容在窄列下也显得紧凑 */
    .el-card {
        padding: 12px;
    }

    /* 响应式：小屏时上传区占比更多 */
    @media (max-width: 900px) {
        .upload-demo.compact {
            padding: 12px;
        }
        .maf-image {
            max-width: 100%;
            max-height: 600px;
        }
    }
</style>
